package org.jeecg.basic.controller;


import cn.hutool.core.net.URLDecoder;
import com.baomidou.dynamic.datasource.annotation.DS;
import org.apache.commons.io.FilenameUtils;
import org.jeecg.basic.entity.FileInfo;
import org.jeecg.basic.entity.MesLineCfg;
import org.jeecg.basic.service.IMesLineCfgService;
import org.jeecg.common.api.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.MalformedURLException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/basic/file")
public class FileController {

    @Value("${app.upload-dir}")
    private String uploadDir;

    @Autowired
    private IMesLineCfgService iMesLineCfgService;

    // 改进后的文件保存方法
    private String generateUniqueFileName(String originalFileName, Path uploadPath) {
//        Path uploadPath = Paths.get(uploadDir);
        String baseName = FilenameUtils.getBaseName(originalFileName);
        String extension = FilenameUtils.getExtension(originalFileName);

        // 清理非法字符（防止路径遍历）
//        String safeBaseName = baseName.replaceAll("[^a-zA-Z0-9\\-]", "_");
        String safeFileName = baseName + (extension.isEmpty() ? "" : "." + extension);

        // 生成唯一文件名
        int counter = 1;
        Path targetPath;
        while (true) {
            targetPath = uploadPath.resolve(safeFileName);
            if (!Files.exists(targetPath)) {
                break;
            }
            safeFileName = String.format("%s(%d)%s",
                    baseName,
                    counter++,
                    extension.isEmpty() ? "" : "." + extension);
        }
        return safeFileName;
    }

    // 文件上传
    @RequestMapping(value ="/upload", method = RequestMethod.POST)
    public ResponseEntity<?> uploadFile(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 1. 获取配置的上传目录
            // 获取当前月份并格式化为yyyyMM（如202503）
            LocalDate currentDate = LocalDate.now();
            DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("yyyyMM");
            String formattedMonth = currentDate.format(monthFormatter);
            Path uploadPath = Paths.get(uploadDir + File.separator + formattedMonth + File.separator).toAbsolutePath().normalize();

            // 2. 强制创建目录（含多级目录）
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
                System.out.println("Created upload directory: " + uploadPath);
            }
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
            for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
                // 获取上传文件对象
                MultipartFile file = entity.getValue();
                // 生成安全且唯一的文件名
                String fileName = generateUniqueFileName(
                        StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())),uploadPath
                );

                // 保存文件（保留原始二进制流）
                Path targetPath = uploadPath.resolve(fileName);
                Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
//                String path = targetPath.toString();
                // 返回文件信息
//                String path = targetPath.toUri().getPath();
                FileInfo fileInfo = new FileInfo(
                        fileName,  // 返回最终存储的名称
                        file.getContentType(),
                        file.getSize(),
                        new Date(),
                        formattedMonth + "//" + fileName
                );
                return ResponseEntity.ok(fileInfo);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseEntity.status(500).body("文件导入失败！");
    }

    // 文件下载
    @GetMapping("/download/**")
    public ResponseEntity<Resource> downloadFile(HttpServletRequest request) {
        String path = extractPathFromPattern(request);
        String decodedPath = URLDecoder.decode(path, StandardCharsets.UTF_8);
        Path filePath = Paths.get(uploadDir).resolve(decodedPath);
        try {
            Resource resource = new UrlResource(filePath.toUri());
            if (resource.exists() && resource.isReadable()) {
                return ResponseEntity.ok()
                        .header(HttpHeaders.CONTENT_DISPOSITION,
                                "attachment; filename=\"" + resource.getFilename() + "\"")
                        .body(resource);
            } else {
                return ResponseEntity.notFound().build();
            }
        } catch (MalformedURLException e) {
            return ResponseEntity.notFound().build();
        }
    }

    // 文件预览
    @GetMapping("/preview")
    public ResponseEntity<?> previewFile( @RequestParam("fileName") String fileName) {
//        String name = "20pn/20250218135009858/20pn_Temp_20250218135009858_24AA022401181044_FOV_0_Result.jpg";
//        String filePath = request.getRequestURI().split("/preview/")[1];
        // 对filePath进行解码处理
        String decodedPath = URLDecoder.decode(fileName, StandardCharsets.UTF_8);
        Path filePath = Paths.get(uploadDir).resolve(decodedPath);
        try {
            String contentType = Files.probeContentType(filePath);
            // 图片直接返回文件流
            if (contentType != null && contentType.startsWith("image/")) {
                Resource resource = new UrlResource(filePath.toUri());
                return ResponseEntity.ok()
                        .contentType(MediaType.parseMediaType(contentType))
                        .body(resource);
            } else {
                String content = new String(Files.readAllBytes(filePath), StandardCharsets.UTF_8);
                return ResponseEntity.ok(content);
            }


//            return ResponseEntity.badRequest().body("不支持预览此文件类型");
        } catch (IOException e) {
            return ResponseEntity.badRequest().body("不支持预览此文件类型");
        }
    }

//    // 文件预览
//    @GetMapping("/preview/**")
//    public ResponseEntity<?> previewFile(HttpServletRequest request, HttpServletResponse response) {
////        String name = "20pn/20250218135009858/20pn_Temp_20250218135009858_24AA022401181044_FOV_0_Result.jpg";
////        String filePath = request.getRequestURI().split("/preview/")[1];
//        // 对filePath进行解码处理
//        String imgPath = extractPathFromPattern(request);
//        String decodedPath = URLDecoder.decode(imgPath, StandardCharsets.UTF_8);
//        Path filePath = Paths.get(uploadDir).resolve(decodedPath);
//        try {
//            String contentType = Files.probeContentType(filePath);
//            // 图片直接返回文件流
//            if (contentType != null && contentType.startsWith("image/")) {
//                Resource resource = new UrlResource(filePath.toUri());
//                return ResponseEntity.ok()
//                        .contentType(MediaType.parseMediaType(contentType))
//                        .body(resource);
//            } else {
//                String content = new String(Files.readAllBytes(filePath), StandardCharsets.UTF_8);
//                return ResponseEntity.ok(content);
//            }
//
//            // 文本文件读取内容
////            if ("text/plain".equals(contentType)) {
////                String content = new String(Files.readAllBytes(filePath), StandardCharsets.UTF_8);
////                return ResponseEntity.ok(content);
////            }
//
////            return ResponseEntity.badRequest().body("不支持预览此文件类型");
//        } catch (IOException e) {
//            return ResponseEntity.badRequest().body("不支持预览此文件类型");
//        }
//    }

    // 获取文件列表
    @GetMapping("/files")
    public Result<List<FileInfo>> listFiles() {
        try {
            List<FileInfo> files = Files.walk(Paths.get(uploadDir))  // 自动递归子目录
                    .filter(Files::isRegularFile)
                    .map(path -> {
                        try {
                            String targetSubstring = "uploads\\";
                            // 查找目标子字符串的位置
                            int index = path.toString().indexOf(targetSubstring);
                            String result = path.toString();
                            if (index != -1) {
                                // 截取目标位置后的内容（包含uploads\自身的长度）
                                result = path.toString().substring(index + targetSubstring.length());
                            } else {
                                System.out.println("未找到目标路径片段");
                            }
                            return new FileInfo( path.getFileName().toString(),
                                    Files.probeContentType(path)==null?"":Files.probeContentType(path),
                                    Files.size(path),
                                    new Date(Files.getLastModifiedTime(path).toMillis()),
                                    result);  // 保持原有映射逻辑
                        } catch (IOException e) {
                            throw new UncheckedIOException(e);
                        }
                    })
                    .collect(Collectors.toList());
            return Result.ok(files);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Result.error("查询文件列表失败！");
    }

    @GetMapping("/getImages")
    @DS("#header.his")
    public Result<List<FileInfo>> getImages(@RequestParam Map<String, String> param) {
        try {
            String stn = param.get("stn");
            String woid = param.get("woid");
            String unitsn = param.get("unitsn");
            MesLineCfg mesLineCfg = iMesLineCfgService.list().get(0);
            String line = param.get("line");
            String load = "\\\\192.168.1.243\\EVQuality$\\"+mesLineCfg.getName()+"\\"+stn+"\\"+woid+"\\"+unitsn;
            if (param.containsKey("tagValue")&& !param.get("tagValue").isEmpty()){
                String tagValue = param.get("tagValue");
                if (!Files.notExists(Paths.get(load)) || Files.isDirectory(Paths.get(load) ) || Files.notExists(Paths.get(tagValue))) {
                    load = this.uploadDir + "\\" + tagValue;
                }else{
                    load = tagValue;
                }
            }
            //拼接上传路径 根据产品查询工单号 获取请求头产线号
            if (Files.notExists(Paths.get(load)) || !Files.isDirectory(Paths.get(load))) {
                // 路径不存在或者不是一个目录，返回空列表或其他处理方式
                return Result.ok(Collections.emptyList());
            }
            List<FileInfo> files = Files.walk(Paths.get(load))  // 自动递归子目录
                    .filter(Files::isRegularFile)
                    .map(path -> {
                        try {
                            String targetSubstring = "uploads\\";
                            // 查找目标子字符串的位置
                            int index = path.toString().indexOf(targetSubstring);
                            String result = path.toString();
                            if (index != -1) {
                                // 截取目标位置后的内容（包含uploads\自身的长度）
                                result = path.toString().substring(index + targetSubstring.length());
                            } else {
                                System.out.println("未找到目标路径片段");
                            }
                            return new FileInfo( path.getFileName().toString(),
                                    Files.probeContentType(path)==null?"":Files.probeContentType(path),
                                    Files.size(path),
                                    new Date(Files.getLastModifiedTime(path).toMillis()),
                                    result);  // 保持原有映射逻辑
                        } catch (IOException e) {
                            throw new UncheckedIOException(e);
                        }
                    })
                    .collect(Collectors.toList());
            return Result.ok(files);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Result.error("查询文件列表失败！");
    }
    /**
     *  把指定URL后的字符串全部截断当成参数
     *  这么做是为了防止URL中包含中文或者特殊字符（/等）时，匹配不了的问题
     * @param request
     * @return
     */
    private static String extractPathFromPattern(final HttpServletRequest request) {
        String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
        String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
        return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
    }
}
